﻿#pragma once
/*!
  file errorcode.h  Definition of erc and erfac classes

  使用错误代码对象进行C++错误处理，可自由选择 基于返回值 或 基于异常 的错误处理风格。

  对于除正常的业务逻辑外，还有 I/O 处理的操作，
  建议使用这个错误处理机制统一处理错误，提高代码的可读性

  使用 logger.h 中的日志功能

  参考文章：https://www.codeproject.com/Articles/5251693/Cplusplus-Error-Handling-with-Error-Code-Objects
  中文翻译版：https://www.cnblogs.com/qinwanlin/p/12669347.html

*/

#include <string>
/*!
 * \class error code 类
 *
 * \brief 通用的错误代码类型，只有错误代码、优先级（严重程度）、是否活跃；
 *          在可用返回值处理的方式，也可以用异常处理的方式（析构时抛出）
 *
 * \author Yunfeng.Bo
 * \date 2023/05/13 14:27
 */
class erc {
public:
    erc()
        : m_code(0)
        , m_active(false) {}

    erc(int value)
        : m_code(value)
        , m_active(0 != value) {}

    erc(const erc& other) = default;
    erc(erc&& other)
        : m_code(other.m_code)
        , m_active(other.m_active) {
        // we become the active error, the other is deactivated
        other.m_active = false;
    }

    virtual ~erc() noexcept(false) {
        if (m_code && m_active)
            raise();
    }

    erc& operator=(const erc& rhs) = default;

    virtual erc& operator=(erc&& rhs) {
        bool rhs_active = rhs.m_active;
        rhs.m_active    = false;   // prevent rhs from throwing if we throw
        if (m_active)
            raise();
        m_code   = rhs.m_code;
        m_active = rhs_active;

        return *this;
    }

    operator int() const {
        m_active = false;
        return m_code;
    }

    erc& reactivate() {
        m_active = true;
        return *this;
    }

    erc& deactivate() {
        m_active = false;
        return *this;
    }

    virtual void raise() {
        m_active = false;
        throw *this;
    }

    inline int  code() const { return m_code; }
    inline void code(int v) { m_code = v; }

protected:
    // bit fields
    int          m_code : 24;
    mutable bool m_active : true;
};

/// The SUCCESS indicator
#define ERR_SUCCESS (erc())
